//
//  SoapUtil.m
//  webservice
//
//  Created by lanyun on 16/3/30.
//  Copyright © 2016年 lanyun. All rights reserved.
//

#import "SoapUtil.h"

@implementation SoapUtil

+ (NSURLSessionDataTask *)SOAP:(NSString *)nameSpace
                      endpoint:(NSString *)endpoint
                        action:(BOOL)action
                        method:(NSString *)method
                    parameters:(nullable id)parameters
                      progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                       success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                       failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{
    NSMutableString *post = [[NSMutableString alloc ] init];
    [post appendString:
     @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
     "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""
     " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""
     " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"
     "<soap:Body>\n" ];
    [post appendString:@"<"];
    [post appendString:method];
    [post appendString:[NSString stringWithFormat:@" xmlns=\"%@\">\n",nameSpace]];
    
    if ([parameters isKindOfClass:[NSDictionary class]]) {
        // NSDictionary
        for (NSString *key in parameters) {
            NSString *value = nil;
            if (key != nil){
                value = [parameters valueForKey:key];
                [post appendString:@"<"];
                [post appendString:key];
                [post appendString:@">"];
                if( value != nil ){
                    [post appendString:value];
                }else{
                    [post appendString:@""];
                }
                [post appendString:@"</"];
                [post appendString:key];
                [post appendString:@">\n"];
            }
        }
    } else if ([parameters isKindOfClass:[NSArray class]]) {
        // NSArray
        for (NSDictionary *dict in parameters){
            NSString *value = nil;
            NSString *key = [[dict keyEnumerator] nextObject];
            if (key != nil){
                value = [dict valueForKey:key];
                [post appendString:@"<"];
                [post appendString:key];
                [post appendString:@">"];
                if( value != nil ){
                    [post appendString:value];
                }else{
                    [post appendString:@""];
                }
                [post appendString:@"</"];
                [post appendString:key];
                [post appendString:@">\n"];
            }
        }
    }
    
    [post appendString:@"</"];
    [post appendString:method];
    [post appendString:@">\n"];
    [post appendString:@"</soap:Body>\n</soap:Envelope>\n"];
    
    NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
    NSString *soapAction = [NSString stringWithFormat:@"%@%@",nameSpace,method];
    NSURL *url=[[NSURL alloc]initWithString:endpoint];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    [request setURL: url ] ;
    [request setHTTPMethod:@"POST"];
    [request setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    if (action) {
        [request setValue:soapAction forHTTPHeaderField:@"SOAPAction"];
    }
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody:postData];
    
    __block NSURLSessionDataTask *dataTask = nil;
    
    NSURLSession *session = [NSURLSession sharedSession];
    dataTask = [session dataTaskWithRequest:request
                          completionHandler:
                ^(NSData *data, NSURLResponse *response, NSError *error) {
                    if (error) {
                        if (failure) {
                            failure(dataTask, error);
                        }
                    } else {
                        if (success) {
                            success(dataTask, data);
                        }
                    }
                }];
    [dataTask resume];
    return dataTask;
}

@end
